﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.Drawing;
using System.Reflection;

namespace OrganizadorFoto {
    class Program {
        static void Main(string[] args) {
            string origem = AppDomain.CurrentDomain.BaseDirectory;
            string destino = origem;
            string tipo = "F";

            if (args.Length > 2) {
                origem = args[0];
                destino = args[1];
                tipo = args[2];
            } else if (args.Length == 1) {
                tipo = args[0];
            }

            tipo = tipo.ToUpper();
            if (tipo != "F" && tipo != "V")
                tipo = "F";
            
            var imagem = new Imagem();
            imagem.ObtemImagem(origem, destino, tipo);
        }

        
    }

    public class Imagem {
        public void ObtemImagem(string origem, string destino, string tipo) {
            DateTime? dataArquivo = null;            

            var listaDeArquivos = new List<string>();
            var raizOrigem = new DirectoryInfo(string.Format(@"{0}\", origem));
            var raizDestino = new DirectoryInfo(string.Format(@"{0}\", destino));
            var arquivosDeImagem = ObtemArquivos(tipo, raizOrigem);

            if (arquivosDeImagem.Count() == 0)
                Console.WriteLine("Não existem arquivos de imagem para processar");
            else {
                Console.WriteLine("*********** Iniciando a cópia de arquivos ***********");
                Console.WriteLine();

                foreach (var arquivo in arquivosDeImagem) {
                    dataArquivo = ObtemDataDoArquivo(arquivo, tipo);
                    string caminho = string.Format("{0} - {1:d2} [{2}]", dataArquivo.Value.Year, dataArquivo.Value.Month, GetDescription((Meses)dataArquivo.Value.Month));

                    if (dataArquivo != null) {
                        var pastaDestino = new DirectoryInfo(string.Format(@"{0}\{1}", raizDestino, caminho));
                        if (!pastaDestino.Exists) {
                            pastaDestino.Create();
                            Console.WriteLine("Criando pasta: {0}", pastaDestino.FullName);
                        }

                        arquivo.CopyTo(string.Format(@"{0}\{1}\{2}", raizDestino, caminho, arquivo.Name), true);
                        Console.WriteLine("Movendo arquivo: {0} --> {1}", arquivo.Name, pastaDestino.Name);
                        listaDeArquivos.Add(arquivo.FullName);
                    }
                }

                Console.WriteLine();
                Console.WriteLine("*********** Iniciando a limpeza dos arquivos ***********");
                Console.WriteLine();

                FileInfo arquivoApagar = null;
                foreach (var nomeArquivo in listaDeArquivos) {
                    arquivoApagar = new FileInfo(nomeArquivo);

                    arquivoApagar.Delete();
                    Console.WriteLine("Apagando arquivo: {0}", arquivoApagar.Name);
                }

                Console.WriteLine();
                Console.WriteLine("{0} arquivos movidos", arquivosDeImagem.Count());
            }            
        }

        private DateTime? ObtemDataDoArquivo(FileInfo arquivo, string tipo) {            

            if (tipo == "F")
                return DataImagem(Image.FromFile(arquivo.FullName));
            if (tipo == "V")
                return arquivo.LastWriteTime;
            
            return null;
        }

        private static FileInfo[] ObtemArquivos(string tipo, DirectoryInfo raizOrigem) {
            var arquivosDeImagem = (tipo == "V") ? raizOrigem.GetFiles("*.mp4") : raizOrigem.GetFiles("*.jpg");
            return arquivosDeImagem;
        }

        public DateTime? DataImagem(Image getImage) {
            using (getImage) {
                int DateTakenValue = 0x9003; //36867;

                if (!getImage.PropertyIdList.Contains(DateTakenValue))
                    return null;

                string dateTakenTag = System.Text.Encoding.ASCII.GetString(getImage.GetPropertyItem(DateTakenValue).Value);
                string[] parts = dateTakenTag.Split(':', ' ');
                int year = int.Parse(parts[0]);
                int month = int.Parse(parts[1]);
                int day = int.Parse(parts[2]);
                int hour = int.Parse(parts[3]);
                int minute = int.Parse(parts[4]);
                int second = int.Parse(parts[5]);

                return new DateTime(year, month, day, hour, minute, second);
            }
        }

        public string GetDescription(Enum en) {
            Type type = en.GetType();

            MemberInfo[] memInfo = type.GetMember(en.ToString());

            if (memInfo != null && memInfo.Length > 0) {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0) {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }

            return en.ToString();
        }
    }

    public enum Meses {
        [Description("Janeiro")]
        JANEIRO = 1,
        [Description("Fevereiro")]
        FEVEREIRO = 2,
        [Description("Março")]
        MARCO = 3,
        [Description("Abril")]
        ABRIL = 4,
        [Description("Maio")]
        MAIO = 5,
        [Description("Junho")]
        JUNHO = 6,
        [Description("Julho")]
        JULHO = 7,
        [Description("Agosto")]
        AGOSTO = 8,
        [Description("Setembro")]
        SETEMBRO = 9,
        [Description("Outubro")]
        OUTUBRO = 10,
        [Description("Novembro")]
        NOVEMBRO = 11,
        [Description("Dezembro")]
        DEZEMBRO = 12
    }
}
